package light.mvc.service.admin.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;

import light.mvc.dao.BaseDaoI;
import light.mvc.model.admin.Tdepartment;
import light.mvc.model.admin.Tresource;
import light.mvc.model.admin.Trole;
import light.mvc.model.admin.Tuser;
import light.mvc.page.admin.User;
import light.mvc.page.base.PageFilter;
import light.mvc.service.admin.UserServiceI;
import light.mvc.utils.MD5Util;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserServiceI {

	@Autowired
	private BaseDaoI<Tuser> userDao;
	
	@Autowired
	private BaseDaoI<Trole> roleDao;
	
	@Autowired
	private BaseDaoI<Tdepartment> departmentDao;

	@Override
	public void add(User user) {
		Tuser t = new Tuser();

		BeanUtils.copyProperties(user, t);
		t.setPassword(MD5Util.md5(user.getPassword()));
		t.setAddTime(new Date());
		
		String idNumber = user.getIdNumber();
		int birthYear = Integer.parseInt(idNumber.substring(6,10));
		Calendar c = Calendar.getInstance(TimeZone.getTimeZone("GMT+08:00"));    //获取东八区时间
		int nowYear = c.get(Calendar.YEAR);    //获取年
		t.setAge(nowYear - birthYear);
		
		if(user.getRoleId() != null) {
			Trole role = roleDao.get(Trole.class, user.getRoleId());
			t.setRole(role);
		}
		
		if(user.getRoleId() == 4 && user.getDepartmentId() != null) {
			Tdepartment department = departmentDao.get(Tdepartment.class,user.getDepartmentId());
			t.setDepartment(department);
		}
		
		userDao.save(t);
	}

	@Override
	public void delete(Integer id) {
		Tuser t = userDao.get(Tuser.class, id);
		userDao.delete(t);
	}

	@Override
	public void edit(User user) {
		Tuser t = userDao.get(Tuser.class,user.getId());
		t.setCellphone(user.getCellphone());
		t.setSex(user.getSex());
		t.setDescription(user.getDescription());
		userDao.update(t);
	}

	@Override
	public User get(Integer id) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		Tuser t = userDao.get("from Tuser t join fetch t.role where t.id = :id", params);
		if(t == null) return null;
		
		User user = new User();
		BeanUtils.copyProperties(t, user);
		
		if(t.getRole() != null) {
			user.setRoleId(t.getRole().getId());
			user.setRoleName(t.getRole().getName());
		}
		if(t.getDepartment() != null) {
			user.setDepartmentId(t.getDepartment().getId());
			user.setDepartmentName(t.getDepartment().getName());
		}
		
		return user;
	}
	
	@Override
	public User login(User userSome) {
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("username", userSome.getUsername());
		params.put("password", MD5Util.md5(userSome.getPassword()));
		Tuser t = userDao.get("from Tuser t join fetch t.role r " +
							"where t.username = :username and t.password = :password", params);
		if (t != null) {	
			User user = new User();
			BeanUtils.copyProperties(t, user);
			List<String> resources = getResources(t.getId());
			user.setResourceList(resources);
			
			String roleName = t.getRole().getName();
			Integer roleId = t.getRole().getId();
			
			user.setRoleId(roleId);
			user.setRoleName(roleName);
			
			return user;
		}
		return null;
	}
	
	@Override
	public List<String> getResources(Integer id) {
		List<String> resourceList = new ArrayList<String>();
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("id", id);
		Tuser t = userDao.get(
				"from Tuser t join fetch t.role r " + 
				" join fetch r.resources where t.id = :id", params);
			if (t != null) {
				Set<Tresource> resources = t.getRole().getResources();
				if ((resources != null) && !resources.isEmpty()) {
					for (Tresource resource : resources) {
						resourceList.add(resource.getUrl());
					}
				}
			}
		return resourceList;
	}
	
	@Override
	public List<User> dataGrid(User userSome, PageFilter ph) {
		List<User> users = new ArrayList<User>();
		Map<String, Object> params = new HashMap<String, Object>();
		String hql = " from Tuser t ";
		List<Tuser> list = userDao.find(hql + whereHql(userSome, params) + orderHql(ph), params, ph.getPage(), ph.getRows());
		for (Tuser t : list) {
			User user = new User();
			BeanUtils.copyProperties(t, user);
			
			user.setRoleId(t.getRole().getId());
			user.setRoleName(t.getRole().getName());
			users.add(user);
		}
		return users;
	}
	
	@Override
	public Long count(User user, PageFilter ph) {
		Map<String, Object> params = new HashMap<String, Object>();
		String hql = " from Tuser t ";
		return userDao.count("select count(*) " + hql + whereHql(user, params), params);
	}

	private String whereHql(User user, Map<String, Object> params) {
		String hql = "";
		if (user != null) {
			hql += " where 1=1 ";
			if (user.getUsername() != null) {
				hql += " and t.username like :username";
				params.put("username", "%" + user.getUsername() + "%");
			}
		}
		return hql;
	}
	
	@Override
	public boolean editUserPwd(Integer id, String oldPwd, String pwd) {
		Tuser u = userDao.get(Tuser.class, id);
		if (u.getPassword().equalsIgnoreCase(MD5Util.md5(oldPwd))) {// 说明原密码输入正确
			u.setPassword(MD5Util.md5(pwd));
			return true;
		}
		return false;
	}

	@Override
	public User getByUsername(User userSome) {
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("username", userSome.getUsername());
		Tuser t = userDao.get("from Tuser t  where t.username = :username",params);
		User user = new User();
		if(t!=null){
			BeanUtils.copyProperties(t, user);
		}else{
			return null;
		}
		return user;
	}
	
	@Override
	public User getByIdNumber(String idNumber) {
		Map<String,Object> params = new HashMap<String,Object>();
		params.put("idNumber", idNumber);
		Tuser t = userDao.get("from Tuser t  where t.idNumber = :idNumber",params);
		User user = new User();
		if(t!=null){
			BeanUtils.copyProperties(t, user);
		}else{
			return null;
		}
		return user;
	}
	
	@Override
	public List<User> doctorGrid(User someDoctor, PageFilter ph) {
		List<User> doctors = new ArrayList<User>();
		Map<String, Object> params = new HashMap<String, Object>();
		
		String hql = "select t from Tuser t join t.role role";
		if(someDoctor.getDepartmentId() != null) {
			params.put("departmentId", someDoctor.getDepartmentId());
			hql += " join t.department department where department.id = :departmentId and role.id = 4";
		} else {
			hql += " where role.id = 4";
		}
		
		List<Tuser> list = userDao.find(hql + orderHql(ph), params, ph.getPage(), ph.getRows());
		
		for (Tuser t : list) {
			User doctor = new User();
			doctor.setId(t.getId());
			doctor.setName(t.getName());
			doctor.setDepartmentId(t.getDepartment().getId());
			doctor.setDepartmentName(t.getDepartment().getName());
			doctors.add(doctor);
		}
		return doctors;
	}
	
	@Override
	public Long doctorGridCount(User someDoctor, PageFilter ph) {
		Map<String, Object> params = new HashMap<String, Object>();
		
		String hql = " from Tuser t join t.role role";
		if(someDoctor.getDepartmentId() != null) {
			params.put("departmentId", someDoctor.getDepartmentId());
			hql += " join t.department department where department.id = :departmentId and role.id = 4";
		} else {
			hql += " where role.id = 4";
		}
		
		return userDao.count("select count(*) " + hql + orderHql(ph), params);
	}
	
	private String orderHql(PageFilter ph) {
		String orderString = "";
		if ((ph.getSort() != null) && (ph.getOrder() != null)) {
			orderString = " order by t." + ph.getSort() + " " + ph.getOrder();
		}
		return orderString;
	}

}
